package cn.zhqr.common.util.map;

import cn.zhqr.common.util.number.NumberUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * 快速创建hashmap的工具类
 * Created by charles on 2017/12/8.
 */
public class MapKit {
    /**
     * 创建hashmap
     * @return
     */
    public static Map hashMap(){
        return new HashMap<>();
    }

    public static Map merge(Map... maps){
        Map new_map = new LinkedHashMap<>();
        for(Map map : maps){
            if(map != null){
                new_map.putAll(map);
            }
        }
        return new_map;
    }
    /**
     * 创建hashmap，并赋值。
     * 调用方式为： MapKit.hashMap("name","Jack","age",28);
     * @param params
     * @return
     */
    public static Map hashMap(Object... params){
        Map map = new HashMap<>();
        for(int i=0;i+1<params.length;i+=2){
            map.put(params[i],params[i+1]);
        }
        return map;
    }

    public static Map linkedHashMap(Object... params){
        Map map = new LinkedHashMap<>();
        for(int i=0;i+1<params.length;i+=2){
            map.put(params[i],params[i+1]);
        }
        return map;
    }

    //内置常用比较器
    public static final Comparator KeyAsc = new MapKeyComparator(Order.asc);//按key字符串正序排列
    public static final Comparator KeyDesc = new MapKeyComparator(Order.desc);//按key字符串倒序排列
    public static final Comparator ValueAsc = new MapValueComparator(Order.asc);//按value正序排列
    public static final Comparator ValueDesc = new MapValueComparator(Order.desc);//按value倒序排列
    public static final Comparator IntAsc = new IntegerComparator(Order.asc);//转换为Integer类型后正序排列
    public static final Comparator IntDesc = new IntegerComparator(Order.desc);//转换为Integer类型后倒序排列

    public static Map sortByKey(Map map) {
        return sortByKey(map,KeyAsc);
    }

    public static Map sortByKey(Map map,Comparator<Comparable> comparator) {
        if (map == null || map.isEmpty()) {
            return map;
        }
        Map sortMap = new TreeMap(comparator);
        sortMap.putAll(map);
        return sortMap;
    }

    public static Map<String, Object> sortByValue(Map<String, ? extends Comparable> oriMap) {
        return sortByValue(oriMap,ValueAsc);
    }
    public static Map<String, Object> sortByValue(Map<String, ? extends Comparable> oriMap,Comparator comparator) {
        if (oriMap == null || oriMap.isEmpty()) {
            return null;
        }
        Map<String, Object> sortedMap = new LinkedHashMap<String, Object>();
        List<Map.Entry<String, ? extends Comparable>> entryList = new ArrayList<Map.Entry<String, ? extends Comparable>>(
                oriMap.entrySet());
        Collections.sort(entryList, comparator);

        Iterator<Map.Entry<String, ? extends Comparable>> iter = entryList.iterator();
        Map.Entry<String, ? extends Comparable> tmpEntry = null;
        while (iter.hasNext()) {
            tmpEntry = iter.next();
            sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
        }
        return sortedMap;
    }

    public static boolean isNotEmpty(Map map) {
        return map!=null && !map.isEmpty();
    }



    public enum Order{
        asc,desc
    }
    public static class MapValueComparator implements Comparator<Map.Entry<String,? extends Comparable>> {
        Order order;
        public MapValueComparator(){
            this(Order.asc);
        }
        public MapValueComparator(Order order){
            this.order = order;
        }
        @Override
        public int compare(Map.Entry<String, ? extends Comparable> me1, Map.Entry<String, ? extends Comparable> me2) {
            if(this.order==Order.asc){
                return me1.getValue().compareTo(me2.getValue());
            }
            return me2.getValue().compareTo(me1.getValue());
        }
    }

    public static class IntegerComparator implements  Comparator<Comparable>{
        Order order;
        public IntegerComparator(){
            this(Order.asc);
        }
        public IntegerComparator(Order order){
            this.order = order;
        }
        @Override
        public int compare(Comparable o1, Comparable o2) {
            if(this.order == Order.asc){
                return NumberUtils.parseInt(o1).compareTo(NumberUtils.parseInt(o2));
            }
            return NumberUtils.parseInt(o2).compareTo(NumberUtils.parseInt(o1));
        }
    }
    public static class MapKeyComparator implements  Comparator<Comparable>{
        Order order;
        public MapKeyComparator(){
            this(Order.asc);
        }
        public MapKeyComparator(Order order){
            this.order = order;
        }
        @Override
        public int compare(Comparable o1, Comparable o2) {
            if(this.order == Order.asc){
                return o1.compareTo(o2);
            }
            return o2.compareTo(o1);
        }
    }

    public static List mapToList(Map map){
        List list = new ArrayList<>();
        for(Map.Entry entry : (Set<Map.Entry>)map.entrySet()){
            list.add(MapKit.hashMap("key",entry.getKey(),"value",entry.getValue()));
        }
        return list;
    }


    /**
     * 将map数值型的value累加，计算总和
     * @param map
     * @return
     */
    public static BigDecimal sumValue(Map map){
        BigDecimal sum = BigDecimal.ZERO;
        if(map != null){
            for(Object value : map.values()){
                if(NumberUtils.isNumber(value+"")){
                   sum = sum.add(new BigDecimal(value+""));
                }
            }
        }
        return sum;
    }
}
